/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package kotionokyurievna.gmail.com.circlebuffer.concur.logic;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 *
 * @author Kateryna_Reznik
 */
public class CircularBuffer {
    private int buffer[];
    private boolean empty;
    private boolean full;
    private int currentRead;
    private int currentWrite;
    private int length;
    private int currentSize;
    private final Lock lock;
    private Condition notFull; 
    private Condition notEmpty ;
    
    public CircularBuffer( int length ){
        setBuffer(length);
        currentRead = 0;
        currentWrite = 0;
        currentSize = 0;
        empty = true;
        full = false;
        lock = new ReentrantLock();
        notEmpty = lock.newCondition();
        notFull = lock.newCondition();
    }
    
    public void setBuffer( int length ){
        if ( length > 0 ){
            buffer = new int[length];
            this.length = length;
        }
        else{
            throw new IllegalArgumentException(" length must be > 0");
        }
    }
    
    public void put( int item ){
        
        lock.lock();
        try {
            while (full) {
               try{
                    notFull.await();
               }
                catch ( InterruptedException iex ){
                    iex.printStackTrace();
                }
            }
            
            buffer[currentWrite] = item;
            currentSize++;
            currentWrite = (currentWrite+1)%length;
            empty = false;
            if ( currentSize == length ){
                full = true;
            }
            notEmpty.signalAll();
        }
        finally{
            lock.unlock();
        }
        
    }
    
    public String get(){
        lock.lock();
        try{
            while (empty) {
                try{
                    notEmpty.await();
               }
                catch ( InterruptedException iex ){
                    iex.printStackTrace();
                }
            }
            String returnValue = buffer[currentRead] + " " + currentRead;
            currentSize--;
            currentRead = (currentRead+1)%length;
            full = false;
            if ( currentSize == 0 ){
                empty = true;
            }
            notFull.signalAll();
            return returnValue;
        }
        finally{
            lock.unlock();
            
        }
        
    }
        
}
